using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Sedna.Core.Controller;
using Sedna.Core.Controller.Common;

namespace Sedna.Core.Controls.Actions
{
    public class ThrowExceptionAction : AbstractAction
    {
        private String exceptionType;
        private String message;
        private String sednaCodeInheritor;
        private String code;
        private String codeName;

        # region Properties

        public string ExceptionType
        {
            set { exceptionType = value; }
        }

        public string Message
        {
            set { message = value; }
        }

        public string SednaCodeInheritor
        {
            set { sednaCodeInheritor = value; }
        }

        public string Code
        {
            set { code = value; }
        }

        public string CodeName
        {
            set { codeName = value; }
        }

        # endregion

        public override IActionResult Execute(IExecutionContext executionContext)
        {
            Type eType = Type.GetType(exceptionType, true);
            
            Exception e;
            
            if (String.IsNullOrEmpty(code) && String.IsNullOrEmpty(codeName))
            {
                if (message == null)
                {
                    ConstructorInfo info = eType.GetConstructor(new Type[] {});

                    e = info.Invoke(new object[] {}) as Exception;
                }
                else
                {
                    ConstructorInfo info = eType.GetConstructor(new Type[] { typeof(String) });

                    e = info.Invoke(new object[] { message }) as Exception;
                }

                                
                throw e;
            }

            ConstructorInfo cInfo;

            if (message == null)
            {
                cInfo = eType.GetConstructor(new Type[] { typeof(int) });
            }
            else
            {
                cInfo = eType.GetConstructor(new Type[] { typeof(int), typeof(String) });
            } 
            
            if (!String.IsNullOrEmpty(code))
            {                                
                if (message == null)
                {
                    e = cInfo.Invoke(new object[] { int.Parse(code) }) as Exception;
                }
                else
                {
                    e = cInfo.Invoke(new object[] { int.Parse(code), message }) as Exception;
                }                
            }
            else
            {
                Type cType = Type.GetType(sednaCodeInheritor, true);

                MethodInfo mInfo = cType.GetMethod("Parse");

                int eCode = Convert.ToInt32(mInfo.Invoke(null, new object[] {codeName}));

                if (message == null)
                {
                    e = cInfo.Invoke(new object[] { eCode }) as Exception;
                }
                else
                {
                    e = cInfo.Invoke(new object[] { eCode, message }) as Exception;
                }                    
            }
            
            throw e;
        }
    }
}
